第十三章笔记

(1)DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()
和 removeEventListener()。所有 DOM 节点中都包含这两个方法,并且它们都接受 3 个参数:要处
理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true,表示在捕获
阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。
要在按钮上为 click 事件添加事件处理程序,可以使用下列代码:

<body>

    <button></button>

    <script>
        var ben = document.getElementById("myBtn");
        ben.addEventListener("click", function () {

            alert(this.id);
        }, false);
      /*上面的代码为一个按钮添加了 onclick 事件处理程序,而且该事件会在冒泡阶段被触发(因为最
后一个参数是 false)。*/
    </script>

上面的代码为一个按钮添加了 onclick 事件处理程序,而且该事件会在冒泡阶段被触发(因为最
后一个参数是 false)。

(2)在不同浏览器中通过能力检测来加减方法处理程序,万金油

<html>



<body>

<button id="clickMe">点我,点我,别害羞</button>
<script>
    /*万金油式处理事件方法*/
    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {

                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + type, handler);
            } else {
                element["on" + type] = handler;
            }
        },
        removeHandler: function (element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent("on" + type, handler);
            } else {
                element["on" + type] = null;
            }

        }
    }

    /*如何使用呢?*/
    var clickme = document.getElementById("clickMe");
    var handler = function () {
        alert("Clicked");
    }

    EventUtil.addHandler(clickme, "click", handler);/*添加事件*/
    EventUtil.removeHandler(clickme, "click", handler);/*移除事件*/

</script>
</body>

</html>

这两个方法首先都会检测传入的元素中是否存在 DOM2 级方法。如果存在 DOM2 级方法,则使用
该方法:传入事件类型、事件处理程序函数和第三个参数 false(表示冒泡阶段)。如果存在的是 IE 的
方法,则采取第二种方案。注意,为了在 IE8 及更早版本中运行,此时的事件类型必须加上”on”前缀。
最后一种可能就是使用 DOM0 级方法(在现代浏览器中,应该不会执行这里的代码)。此时,我们使用
的是方括号语法来将属性名指定为事件处理程序,或者将属性设置为 null。

(3)在一个函数里面处理多个事件时,可以用type属性

<html>
<body>
    <button id="clickMe">点我,点我,别害羞</button>
    <script>
        var btn = document.getElementById("clickMe");
        var handler = function (event) {

            switch (event.type) {
                case "click":
                    alert("clickMe,ye");
                    break;
                case "mouseover":
                    event.target.style.backgroundColor = "red";
                    break;
            }
        }

        btn.onclick = handler;
        btn.onmouseover = handler;
    </script>
</body>

</html>

我们以此给了btn加了三个事件。只用了一个函数。

(4)跨浏览器的事件对象,以下代码可以再IE和其他浏览器运行,做好了能力检测。万金油

<html>

<body>
    <button id="clickMe">点我,点我,别害羞</button>
    <script>
        var EventUtil = {
            addHandler: function (element, type, handler) {
                //省略的代码,上面有
            },
            getEvent: function (event) {
                return event ? event : window.event;
            },
            getTarget: function (event) {
                return event.target || event.srcElement;
            },

            preventDefault: function (event) {
                if (event.preventDefault) {
                    event.preventDefault();
                } else {
                    event.returnValue = false;
                }
            },

            removeHandler: function (element, type, handler) {
                //省略的代码,上面例子有
            },
            stopPropagation: function (event) {
                if (event.stopPropagation) {
                    event.stopPropagation();
                } else {
                    event.cancelBubble = true;
                }
            }
        };


    </script>
</body>

</html>

(4)事件类型

1 确定浏览器是否支持DOM2级事件可以用以下代码

var isSupported = document.implementation.hasFeature("HTMLEvents", "2.0");  

注意,只有根据“DOM2 级事件”实现这些事件的浏览器才会返回 true。而以非标准方式支持这
些事件的浏览器则会返回 false。要确定浏览器是否支持“DOM3 级事件”定义的事件,可以使用如下
代码:

var isSupported = document.implementation.hasFeature("UIEvent", "3.0"); 

(5)load事件引起加载script文件

EventUtil.addHandler(window, "load", function () {
    var script = document.createElement("script");
    EventUtil.addHandler(script, "load", function (event) {
        alert("LoadedScript");
    });
    script.src = "demo.js";
    document.body.appendChild(script);
})

以上可以给文档加载时加一个加载js文件的方法.666

(6)以下列举一些事件,没事看看.

  • 当浏览器窗口被调整到一个新的高度或宽度时,就会触发 resize 事件。
 EventUtil.addHandler(window, "resize", function(event){  
 alert("Resized");  
}); 
  • 当焦点从页面中的一个元素移动到另一个元素,会依次触发下列事件:
    (1) focusout 在失去焦点的元素上触发;
    (2) focusin 在获得焦点的元素上触发;
    (3) blur 在失去焦点的元素上触发;
    (4) DOMFocusOut 在失去焦点的元素上触发;
    (5) focus 在获得焦点的元素上触发;
    (6) DOMFocusIn 在获得焦点的元素上触发。
    其中,blur、DOMFocusOut 和 focusout 的事件目标是失去焦点的元素;而 focus、DOMFocusIn
    和 focusin 的事件目标是获得焦点的元素。
    要确定浏览器是否支持这些事件,可以使用如下代码:
var isSupported = document.implementation.hasFeature("FocusEvent", "3.0"); 

(7)可以通过获取鼠标点击的位置来显示鼠标点击的位置.

<html>

<body>
  <div  id="myDiv"  style="width: 100%;height: 300px;"></div>

<script>
    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + type, handler);
            } else {
                element["on" + type] = handler;
            }

        },
        getEvent: function (event) {
            return event ? event : window.event;
        },
        getTarget: function (event) {
            return event.target || event.srcElement;
        },

        preventDefault: function (event) {
            if (event.preventDefault) {
                event.preventDefault();
            } else {
                event.returnValue = false;
            }
        },

        removeHandler: function (element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent("on" + type, handler);
            } else {
                element["on" + type] = null;
            }

        },
        stopPropagation: function (event) {
            if (event.stopPropagation) {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }
    };



   var div=document.getElementById("myDiv");
   EventUtil.addHandler(div,"click",function(event){
       event=EventUtil.getEvent(event);
       alert("Page coordinates:"+event.pageX+","+event.pageY);
   })


</script>
</body>

</html>

(8)检测用户是否同时按下了键盘键

var div=document.getElementById("myDiv");
EventUtil.addHandler(div,"click",function(event){
    event=EventUtil.getEvent(event);
   var keys=new Array();
   if(event.shiftKey){
             keys.push("shift");

   }
   if(event.ctrlKey){
             keys.push("ctrl");

   }
   if(event.altKey){
             keys.push("alt");

   }

alert(keys.join(","));

})

这里检测用户是否同时按下了shift,ctrl,alt

(9)键盘和文本事件

var textBox=document.getElementById("MyText");
EventUtil.addHandler(textBox,"keyup",function(event){
    event=EventUtil.getEvent(event);
    alert(event.keyCode);
})

以上代码能帮助我们捕获到用户点击文本框的的键盘的键码进而显示。

(10)事件委托

对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事
件处理程序,就可以管理某一类型的所有事件。例如,click 事件会一直冒泡到 document 层次。
也就是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事
件处理程序。以下面的 HTML 代码为例。

HTML
 <ul id="myLinks">
        <li id="goSomewhere">Go somewhere</li>
        <li id="doSomething">Do something</li>
        <li id="sayHi">Say hi</li>
       </ul> 

    /*如果在一个复杂的 Web 应用程序中,对所有可单击的元素都采用这种方式,那么结果就会有数不
清的代码用于添加事件处理程序。此时,可以利用事件委托技术解决这个问题。使用事件委托,只需在
DOM 树中尽量最高的层次上添加一个事件处理程序,如下面的例子所示。*/
JAVASCRIPT  
   var list=document.getElementById("myLinks");
   EventUtil.addHandler(list,"click",function(event){
    event=EventUtil.getEvent(event);
   var target=EventUtil.getTarget(event);
   switch(target.id){
      case "doSomething":
          document.title="I changed the document's title";
          break;
      case "goSomewhere":
      location.href= "http://www.wrox.com"; 
      break;
      case "sayHi":
        alert("hi");
        break;
  }
   });

所有的按钮事件都可以用这种,取最高层次上的事件处理程序来处理。

(11)模拟鼠标事件

html

<button  id="myBtn">nihoa</button>

javascript

 var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEvent("MouseEvents");

btn.onclick=function(){
    alert("nihao");
}
//初始化事件对象
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
 false, false, false, false, 0, null);

//触发事件
btn.dispatchEvent(event); 

(12)小结

事件是将 JavaScript 与网页联系在一起的主要方式。“DOM3 级事件”规范和 HTML5 定义了常见的
大多数事件。即使有规范定义了基本事件,但很多浏览器仍然在规范之外实现了自己的专有事件,从而
为开发人员提供更多掌握用户交互的手段。有些专有事件与特定设备关联,例如移动 Safari 中的
orientationchange 事件就是特定关联 iOS 设备的。
在使用事件时,需要考虑如下一些内存与性能方面的问题。

1 有必要限制一个页面中事件处理程序的数量,数量太多会导致占用大量内存,而且也会让用户
感觉页面反应不够灵敏。
2建立在事件冒泡机制之上的事件委托技术,可以有效地减少事件处理程序的数量。
*3建议在浏览器卸载页面之前移除页面中的所有事件处理程序。
可以使用 JavaScript 在浏览器中模拟事件。“DOM2 级事件”和“DOM3 级事件”规范规定了模拟事
件的方法,为模拟各种有定义的事件提供了方便。此外,通过组合使用一些技术,还可以在某种程度上
模拟键盘事件。IE8 及之前版本同样支持事件模拟,只不过模拟的过程有些差异。
事件是 JavaScript 中最重要的主题之一,深入理解事件的工作机制以及它们对性能的影响至关重要。

鲍志强 wechat
欢迎你扫一扫上面的微信公众号,订阅我的博客!
你的点赞是为了你的未来